Skip to content

fix(markdown): add backslash-escape handling in parser and serializer#7898

Merged
bdbch merged 3 commits into
mainfrom
fix/7258-markdown-escaped-content-formatting
Jun 1, 2026
Merged

fix(markdown): add backslash-escape handling in parser and serializer#7898
bdbch merged 3 commits into
mainfrom
fix/7258-markdown-escaped-content-formatting

Conversation

@bdbch
Copy link
Copy Markdown
Member

@bdbch bdbch commented May 30, 2026

Changes Overview

Fix backslash-escape handling in @tiptap/markdown. Backslash-escaped markdown characters (e.g. \*, \_, \\) were silently dropped during parsing, and markdown-significant characters in text nodes were not escaped during serialization.

Implementation Approach

Two-pronged fix in MarkdownManager.ts:

Parsing (Markdown → ProseMirror): Added handling for marked.js escape tokens in both parseInlineTokens and parseFallbackToken. The escape token's text property (the escaped character) is used directly to create a text node. Adjacent text nodes are merged to match ProseMirror's expectations.

Serialization (ProseMirror → Markdown): Added escapeMarkdownSyntax() method that backslash-escapes markdown-significant characters (\, `, *, _, [, ], ~) in text nodes during serialization. This runs after HTML entity encoding and respects the existing isInsideCode guard so code blocks/marks remain untouched.

The solution is generic — it works with all extensions since escapes are handled at the manager level, not per-extension.

Testing Done

  • Added 18 new test cases covering: parsing various escaped chars, mixed escaped + real formatting, serialization escaping for all 7 chars, round-trip stability, and code block/mark exemption
  • All 1090 tests pass (119 test files)
  • Lint and build pass cleanly

Verification Steps

  1. Enable the @tiptap/markdown extension in the demo
  2. Type \*text\* → should display literal *text*, not italic
  3. Type \\ → should display a single backslash
  4. Type \_text\_ → should display literal _text_, not italic
  5. Verify round-trip: the markdown output re-parses correctly

Additional Notes

N/A

AI Usage

  • I have used AI tools (e.g., ChatGPT, Claude, Copilot) in creating this PR.
    • AI assisted with code implementation and test scaffolding
    • AI generated this PR description

Checklist

  • I have created a changeset for this PR if necessary.
  • My changes do not break the library.
  • I have added tests where applicable.
  • I have followed the project guidelines.
  • I have fixed any lint issues.

Related Issues

Closes #7258

Copilot AI review requested due to automatic review settings May 30, 2026 13:00
@netlify
Copy link
Copy Markdown

netlify Bot commented May 30, 2026

Deploy Preview for tiptap-embed ready!

Name Link
🔨 Latest commit 4b9bfd3
🔍 Latest deploy log https://app.netlify.com/projects/tiptap-embed/deploys/6a1d6e192ac0b300085d41d7
😎 Deploy Preview https://deploy-preview-7898--tiptap-embed.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 30, 2026

🦋 Changeset detected

Latest commit: 4b9bfd3

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 72 packages
Name Type
@tiptap/core Patch
@tiptap/markdown Patch
@tiptap/extension-audio Patch
@tiptap/extension-blockquote Patch
@tiptap/extension-bold Patch
@tiptap/extension-bubble-menu Patch
@tiptap/extension-code-block-lowlight Patch
@tiptap/extension-code-block Patch
@tiptap/extension-code Patch
@tiptap/extension-collaboration-caret Patch
@tiptap/extension-collaboration Patch
@tiptap/extension-details Patch
@tiptap/extension-document Patch
@tiptap/extension-drag-handle Patch
@tiptap/extension-emoji Patch
@tiptap/extension-file-handler Patch
@tiptap/extension-floating-menu Patch
@tiptap/extension-hard-break Patch
@tiptap/extension-heading Patch
@tiptap/extension-highlight Patch
@tiptap/extension-horizontal-rule Patch
@tiptap/extension-image Patch
@tiptap/extension-invisible-characters Patch
@tiptap/extension-italic Patch
@tiptap/extension-link Patch
@tiptap/extension-list Patch
@tiptap/extension-mathematics Patch
@tiptap/extension-mention Patch
@tiptap/extension-node-range Patch
@tiptap/extension-paragraph Patch
@tiptap/extension-strike Patch
@tiptap/extension-subscript Patch
@tiptap/extension-superscript Patch
@tiptap/extension-table-of-contents Patch
@tiptap/extension-table Patch
@tiptap/extension-text-align Patch
@tiptap/extension-text-style Patch
@tiptap/extension-text Patch
@tiptap/extension-twitch Patch
@tiptap/extension-typography Patch
@tiptap/extension-underline Patch
@tiptap/extension-unique-id Patch
@tiptap/extension-youtube Patch
@tiptap/extensions Patch
@tiptap/html Patch
@tiptap/react Patch
@tiptap/static-renderer Patch
@tiptap/suggestion Patch
@tiptap/vue-2 Patch
@tiptap/vue-3 Patch
@tiptap/extension-drag-handle-react Patch
@tiptap/extension-drag-handle-vue-2 Patch
@tiptap/extension-drag-handle-vue-3 Patch
@tiptap/extension-bullet-list Patch
@tiptap/extension-ordered-list Patch
@tiptap/extension-list-item Patch
@tiptap/extension-list-keymap Patch
@tiptap/extension-task-item Patch
@tiptap/extension-task-list Patch
@tiptap/extension-table-cell Patch
@tiptap/extension-table-header Patch
@tiptap/extension-table-row Patch
@tiptap/extension-color Patch
@tiptap/extension-font-family Patch
@tiptap/extension-character-count Patch
@tiptap/extension-dropcursor Patch
@tiptap/extension-focus Patch
@tiptap/extension-gapcursor Patch
@tiptap/extension-history Patch
@tiptap/extension-placeholder Patch
@tiptap/pm Patch
@tiptap/starter-kit Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes markdown backslash-escape handling in @tiptap/markdown so escaped punctuation is preserved on parse and markdown-significant characters in plain text are escaped on serialize, improving round-trip stability and preventing accidental formatting.

Changes:

  • Parse marked.js escape tokens as literal text nodes (so \*, \_, \\, etc. are not dropped).
  • Merge adjacent text nodes with identical marks after inline parsing to keep JSON output compact/consistent.
  • Escape markdown-significant characters during serialization for non-code text nodes to avoid unintended formatting on re-parse.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
packages/markdown/src/MarkdownManager.ts Adds parsing support for escape tokens, merges adjacent compatible text nodes, and escapes markdown syntax during text serialization (outside code contexts).
packages/markdown/tests/conversion.spec.ts Adds regression coverage for parsing escaped characters, serialization escaping, round-trip stability, and code-context exemptions.
.changeset/fix-markdown-escape-handling.md Publishes the user-facing fix as a patch changeset for @tiptap/markdown.

alexvcasillas
alexvcasillas previously approved these changes Jun 1, 2026
Copy link
Copy Markdown
Contributor

@alexvcasillas alexvcasillas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good 👍🏻 Just dropped a small question about the JSON.stringify equal comparison

Comment thread packages/markdown/src/MarkdownManager.ts Outdated
Replace JSON.stringify-based mark comparison in MarkdownManager with
marksEqual. Add unit tests for marksEqual covering key order, missing
attrs, length and type differences
Export attrsEqual and marksEqual from @tiptap/core utilities.
Add unit tests for both, remove duplicated implementations in the
markdown package, and add a changeset
@bdbch bdbch merged commit 9cf8db0 into main Jun 1, 2026
3 of 4 checks passed
@bdbch bdbch deleted the fix/7258-markdown-escaped-content-formatting branch June 1, 2026 11:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Markdown extension misinterprets some escaped characters as formatting

3 participants